package flexo.examples;

import flexo.input.Event;
import flexo.math.Vector;
import flexo.physic.force.SimpleForce;
import flexo.physic.force.Spring;
import flexo.graphic.Color;

public class Test_Physic_General extends Test_Graphic_Base implements flexo.input.EventListener
{
	flexo.scene.Node root;
	flexo.scene.Node gridNode;
	flexo.scene.Node ballNode;
	flexo.scene.Node hookNode;
	
	flexo.scene.Node shadowNode;
	
	flexo.physic.entity.Entity ballPhysics;
	
	public static float SPEED = 14;
	
	SimpleForce[] sf;
		
	public static void main(String[] args)
	{
		run("flexo.examples.Test_Physic_General");
	}
	
	public void init()
	{
		super.init();
		root = mainScene.addChild("root");
		gridNode = root.addChild("grid");
		hookNode = mainScene.addChild("hook");		
		
		// Grid
		
		flexo.graphic.Material mat = graphic.addMaterial("gridMat", "textureRepeat");
		flexo.graphic.ShaderParam param = mat.getShaderParam("tex");
		param.setValue("textures/blocks.jpg");
		param = mat.getShaderParam("repeatU");
		param.setValue(20.0f);
		param = mat.getShaderParam("repeatV");
		param.setValue(20.0f);
		
		flexo.graphic.entity.Entity grid = graphic.addQuad(20, 20);
		grid.setMaterial("gridMat");
		grid.attachTo(gridNode);
		gridNode.setRotation(new flexo.math.Quaternion(new flexo.math.Vector(1,0,0),-90.0f));
		gridNode.setPosition(new flexo.math.Vector(0,-1,0));
		
		// Ball
		
		mat = graphic.addMaterial("billMat", "billboard");
		mat.setBlending(flexo.graphic.Material.Blending.TRANSPARENT_MASK);
		param = mat.getShaderParam("tex");
		param.setValue("textures/beachball.png");
		
		ballNode = mainScene.addChild("ball");
		flexo.graphic.entity.Entity billboard = graphic.addQuad(1, 1);
		billboard.setMaterial("billMat");
		billboard.attachTo(ballNode);
		
		ballPhysics = physics.addSphere(1,1);
		//ballPhysics.setGravity(9.8f);
		ballPhysics.setDamping(0.995f);
		ballPhysics.attachTo(ballNode);
		
		sf = new SimpleForce[4];
		sf[0] = physics.addSimpleForce("fMoveForward", new Vector(0,0,-1));
		sf[1] = physics.addSimpleForce("fMoveBackward", new Vector(0,0,1));
		sf[2] = physics.addSimpleForce("fMoveLeft", new Vector(-1,0,0));
		sf[3] = physics.addSimpleForce("fMoveRight", new Vector(1,0,0));
		
		// DRAG
		//physics.addDragForce("drag", 1, 1f);
		//ballPhysics.applyForce("drag");
		
		// SPRING
		Spring spring = physics.addSpringForce("spring", hookNode, 1);
		spring.setElasticity(15);
		ballPhysics.applyForce("spring");
		
		// MOVEMENT
		ballPhysics.applyForce("fMoveForward");
		ballPhysics.applyForce("fMoveBackward");
		ballPhysics.applyForce("fMoveLeft");
		ballPhysics.applyForce("fMoveRight");
				
		input.addAction("ballForward", flexo.input.EventType.KEY_I);
		input.addAction("ballBackward", flexo.input.EventType.KEY_K);
		input.addAction("ballLeft", flexo.input.EventType.KEY_J);
		input.addAction("ballRight", flexo.input.EventType.KEY_L);
		
		input.addEventListener(this);
		
		// Hook
		hookNode.setPosition(new Vector(0,2,0));
		mat = graphic.addMaterial("hook", "oneColorBillboard");
		param = mat.getShaderParam("color");
		param.setValue(Color.RED);
		flexo.graphic.entity.Entity square = graphic.addQuad(0.25f, 0.25f);
		square.setMaterial("hook");
		square.attachTo(hookNode);
		
		// Shadow
		shadowNode = mainScene.addChild("shadow");
		mat = graphic.addMaterial("shadowMat", "default");
		mat.setBlending(flexo.graphic.Material.Blending.TRANSPARENT_MULTIPLY);
		param = mat.getShaderParam("tex");
		param.setValue("textures/dotshadow.jpg");
		
		flexo.graphic.entity.Entity shadow = graphic.addQuad(1, 1);
		shadow.setMaterial("shadowMat");
		shadow.attachTo(shadowNode);
		shadowNode.setRotation(new flexo.math.Quaternion(new flexo.math.Vector(1,0,0),-90.0f));
	}

	public void cleanUp()
	{
	}	

	public void update()
	{
		Vector shadowPos = Vector.getTempVector();
		shadowPos.set(ballNode.getPosition());
		shadowPos.y = -0.9f;
		shadowNode.setPosition(shadowPos);
		
		float scale = ballNode.getPosition().y + 1;
		scale = 1.5f - ( (scale/4) * 1.5f);
		if (scale < 0)
		{
			scale = 0;
		}
		shadowNode.setScale(scale);
	}

	@Override
	public void processEvent(Event e)
	{
		if (e.check("ballForward"))
		{
			if (e.getValue() > 0)
			{
				sf[0].setMagnitude(SPEED);
			}
			else
			{
				sf[0].setMagnitude(0);
			}
		}
		else if (e.check("ballBackward"))
		{
			if (e.getValue() > 0)
			{
				sf[1].setMagnitude(SPEED);
			}
			else
			{
				sf[1].setMagnitude(0);
			}
		}
		else if (e.check("ballLeft"))
		{
			if (e.getValue() > 0)
			{
				sf[2].setMagnitude(SPEED);
			}
			else
			{
				sf[2].setMagnitude(0);
			}
		}
		else if (e.check("ballRight"))
		{
			if (e.getValue() > 0)
			{
				sf[3].setMagnitude(SPEED);
			}
			else
			{
				sf[3].setMagnitude(0);
			}
		}
	}
}
